added SSCLI 1.0
[windows-sources.git] / shared source / wpf / src / host / shimimpl / persistmoniker.cxx
blob0b52b52dc3918aad53018dbd325b127afe191b0d
1 //+-----------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // Description:
6 // Implements the PersistMoniker class of PresentationHost.
7 //
8 // History:
9 // 2002/06/19-murrayw
10 // Created
11 // 2003/06/30/03-[....]
12 // Ported ByteRangeDownloader to WCP
13 // 2007/09/20-[....]
14 // Ported Windows->DevDiv. See SourcesHistory.txt.
15 // Removed dependence on ByteWrapper[Impl] and DownloadInfo for PresentationHost.exe.
17 //------------------------------------------------------------------------
19 #include "Precompiled.hxx"
20 #include "PersistMoniker.hxx"
21 #include "HostShim.hxx"
22 #include "BindStatusCallback.hxx"
23 #include "ShimUtilities.hxx"
25 //******************************************************************************
27 // CPersistMoniker::CPersistMoniker()
29 //******************************************************************************
31 CPersistMoniker::CPersistMoniker(__in CHostShim *pHostShim)
33 m_pHostShim = pHostShim;
36 //*******************************************************************************
38 // CPersistMoniker::~CPersistMoniker()
40 //******************************************************************************
42 CPersistMoniker::~CPersistMoniker()
46 //******************************************************************************
48 // CPersistMoniker::QueryInterface()
50 //******************************************************************************
52 STDMETHODIMP CPersistMoniker::QueryInterface(REFIID riid, __out LPVOID *ppReturn)
54 return m_pHostShim->QueryInterface(riid, ppReturn);
57 //******************************************************************************
59 // CPersistMoniker::AddRef()
61 //******************************************************************************
63 STDMETHODIMP_(ULONG) CPersistMoniker::AddRef()
65 return m_pHostShim->AddRef();
68 //******************************************************************************
70 // CPersistMoniker::Release()
72 //******************************************************************************
74 STDMETHODIMP_(ULONG) CPersistMoniker::Release()
76 return m_pHostShim->Release();
79 //******************************************************************************
81 // CPersistMoniker::GetClassID()
83 //******************************************************************************
85 STDMETHODIMP CPersistMoniker::GetClassID(__out LPCLSID pClassID)
87 return m_pHostShim->GetClassID(pClassID);
90 //******************************************************************************
92 // CPersistMoniker::Save()
94 //******************************************************************************
96 STDMETHODIMP CPersistMoniker::Save(LPMONIKER, LPBC, BOOL)
98 return S_OK;
101 //******************************************************************************
103 // CPersistMoniker::GetCurMoniker()
105 //******************************************************************************
107 STDMETHODIMP CPersistMoniker::GetCurMoniker(LPMONIKER*)
109 return S_OK;
112 //******************************************************************************
114 // CPersistMoniker::SaveCompleted()
116 //******************************************************************************
118 STDMETHODIMP CPersistMoniker::SaveCompleted(LPMONIKER, LPBC)
120 return S_OK;
123 #define MAX_SCHEMA 64
125 //******************************************************************************
127 // CPersistMoniker::Load()
129 //******************************************************************************
131 STDMETHODIMP CPersistMoniker::Load(BOOL fFullyAvailable,
132 __in LPMONIKER pMoniker,
133 __in LPBC pbc,
134 DWORD)
136 HRESULT hr = S_OK;
138 EventWriteWpfHostUm_IPersistMonikerLoadStart();
140 m_pHostShim->SetActivationType(MonikerActivation);
142 LPOLESTR pwszURL = NULL;
143 WCHAR pszResult[INTERNET_MAX_URL_LENGTH + 1];
145 CComPtr<CBindStatusCallback> spBindStatusCallback;
146 CComPtr<IFillLockBytes> spFlb;
147 CComPtr<IMoniker> spMkNew;
148 CComPtr<IBindCtx> spBCNew;
150 m_pHostShim->SetAllowPersistFileLoad(FALSE);
152 CK_PARG(pMoniker);
153 CKHR(pMoniker->GetDisplayName(pbc, pMoniker, &pwszURL));
154 CK_ALLOC(pwszURL);
155 m_pHostShim->SetStartupUri(pwszURL);
157 DWORD cchResult;
158 CKHR(CoInternetParseUrl(pwszURL,
159 PARSE_SCHEMA,
160 NULL,
161 pszResult,
162 INTERNET_MAX_URL_LENGTH + 1,
163 &cchResult,
164 0));
165 // If we are a local file, FAIL to load from the IPersistMoniker
166 // so that we will load from the IPersistFile, instead.
170 if (cchResult == 4 && _wcsnicmp(pszResult,L"file",4) == 0)
172 if (fFullyAvailable)
174 hr = E_FAIL; // E_FAIL
176 else
178 hr = S_FALSE; // S_FALSE
181 //Returning E_NOTIMPL for now to work around a urlmon bug
182 //hr = E_NOTIMPL;
184 //We will allow IPersistFile::Load only for local files. If IPersistMoniker::Load
185 //fails for http urls, urlmon will then call IPersistFile::Load with the
186 //cache filename. It is unsafe and incorrect for us to allow that load since
187 //we will grant elevated security privileges and also relative references will
188 //no longer work
189 m_pHostShim->SetAllowPersistFileLoad(TRUE);
191 goto Cleanup;
194 spBindStatusCallback = new CBindStatusCallback();
195 CK_ALLOC(spBindStatusCallback);
196 //!!! Make sure to set BINDINFO_OPTIONS_ENABLE_UTF8 in all implementations of IBindStatusCallback.
197 //!!! It is needed for correct encoding of non-ASCII characters in URL paths, per RFC 3986 & 3987.
199 // UrlMon Workaround: UrlMon was returning the wrong file size information for files that
200 // were in the cache. Our past workaround was to delete the cache file, however IE suggested
201 // that we create a new Moniker and BindContext before binding to storage. This would allow
202 // us to use the cache file if the content has not expired.
203 CKHR(CreateURLMonikerEx(NULL, pwszURL, &spMkNew, URL_MK_UNIFORM));
204 CKHR(CreateBindCtx( 0, &spBCNew ));
205 CKHR(RegisterBindStatusCallback(spBCNew, spBindStatusCallback, NULL, 0));
207 CKHR(spMkNew->BindToStorage(spBCNew,
208 NULL,
209 IID_IStream,
210 reinterpret_cast<void**>(&(spBindStatusCallback->m_pStream))));
211 if (!FAILED(hr))
213 hr = S_OK;
216 BOOL fReceivedWmQuit;
218 MsgWaitForSingleObject(spBindStatusCallback->m_hMimeArrivedEvent, INFINITE, &fReceivedWmQuit);
220 m_pHostShim->SetMimeType(spBindStatusCallback->GetMimeType());
222 if ((m_pHostShim->GetMimeType() == MimeType_Application) ||
223 (m_pHostShim->GetMimeType() == MimeType_Markup))
225 MsgWaitForSingleObject(spBindStatusCallback->m_hManifestAvailableEvent, INFINITE, &fReceivedWmQuit);
226 m_pHostShim->SetLocalDeploymentManifestPath(spBindStatusCallback->GetCacheFilename());
227 // Trigger DownloadCompleted since downloading is performed in managed code.
228 SignalAvalonStartupRelatedEvent(m_pHostShim->GetDownloadCompletedEvent());
230 else
232 CKHR(E_INVALIDARG);
235 // Note: CHostShim::Execute() is called below.
236 hr = S_OK;
238 Cleanup:
239 // We purposefully return E_FAIL to cause IPersistFile loading.
240 if (!m_pHostShim->GetAllowPersistFileLoad())
242 // Handle downloading error from UrlMon
243 if (FAILED(hr) && spBindStatusCallback)
245 HRESULT bindResult = spBindStatusCallback->GetBindResult();
246 if(FAILED(bindResult))
248 hr = bindResult;
249 wchar_t *pErrMsg = TryDecodeDownloadError(hr);
250 if(pErrMsg)
252 // The easiest thing to do is call MessageBox() here. But the browser still has the
253 // foreground window status, so the message box will show minimized or behind.
254 // The solution is to fully activate the DocObject so that it can show the error page.
255 m_pHostShim->SetErrorMessageToDisplay(pErrMsg);
256 LocalFree(pErrMsg);
257 hr = S_OK; // Don't fail. We are activating, after all.
262 if(SUCCEEDED(hr))
264 // Note: Execute() triggers Watson on any failure.
265 m_pHostShim->Execute();
267 else
269 HANDLE_ACTIVATION_FAULT(hr);
273 if (pwszURL != NULL)
275 CoTaskMemFree(pwszURL);
278 EventWriteWpfHostUm_IPersistMonikerLoadEnd(hr);
280 return hr;
283 //******************************************************************************
285 // CPersistMoniker::IsDirty()
287 //******************************************************************************
289 STDMETHODIMP CPersistMoniker::IsDirty()
291 return S_FALSE;